/*********************************************************************************
 *      Copyright:  (C) 2024 dengleen
 *                  All rights reserved.
 *
 *       Filename:  pwm.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(07/05/24)
 *         Author:  dengleen <dengleen@outlook.com>
 *      ChangeLog:  1, Release initial version on "07/05/24 08:46:30"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include "pwm.h"

static char pwm_path[100];


static int pwm_config(const char *attr, const char *val)
{
	char file_path[100];
	int len;
	int fd =  -1;

	if(attr == NULL || val == NULL)
	{
		printf("[%s] argument error\n", __FUNCTION__);
		return -1;
	}

	memset(file_path, 0, sizeof(file_path));
	snprintf(file_path, sizeof(file_path), "%s/%s", pwm_path, attr);
	if (0 > (fd = open(file_path, O_WRONLY))) {
		printf("[%s] open %s error\n", __FUNCTION__, file_path);
		return fd;
	}

	len = strlen(val);
	if (len != write(fd, val, len)) {
		printf("[%s] write %s to %s error\n", __FUNCTION__, val, file_path);
		close(fd);
		return -2;
	}

	close(fd);  
	return 0;
}

int buzzer(char *on_or_off)
{
	char temp[100];
	int fd = -1;

#if 0
	if (4 != argc) {
		printf("usage: %s <id> <period> <duty>\n", argv[0]);
		exit(-1);  
	}


	printf("PWM config: id<%s>, period<%s>, duty<%s>\n", argv[1], argv[2], argv[3]);

#endif
	memset(pwm_path, 0, sizeof(pwm_path));
	snprintf(pwm_path, sizeof(pwm_path), "/sys/class/pwm/pwmchip%s/pwm0", "0");


	memset(temp, 0, sizeof(temp));
	if (access(pwm_path, F_OK)) {
		snprintf(temp, sizeof(temp) , "/sys/class/pwm/pwmchip%s/export", "0");
		if (0 > (fd = open(temp, O_WRONLY))) {
			printf("open pwmchip%s error\n", "0");
			exit(-1);
		}

		if (1 != write(fd, "0", 1)) {
			printf("write '0' to  pwmchip%s/export error\n", "0");
			close(fd);
			exit(-2);
		}

		close(fd); 
	}


	if (pwm_config("period", "1000000"))
		exit(-1);


	if (pwm_config("duty_cycle", "800000"))
		exit(-1);


	pwm_config("enable", on_or_off);

	return 0;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("用法: %s <on|off>\n", argv[0]);
        return -1;
    }

    if (strcmp(argv[1], "on") != 0 && strcmp(argv[1], "off") != 0) {
        printf("参数错误，只能输入 'on' 或 'off'\n");
        return -1;
    }

    if (buzzer(argv[1]) != 0) {
        printf("蜂鸣器控制失败\n");
        return -1;
    }

    printf("蜂鸣器状态已设置为: %s\n", argv[1]);
    return 0;
}
